#include <string>
#include <map>
#include <iostream>
#include <fstream>
#include <stdexcept>
#include <vector>


std::string binaryToHex(const std::string& binaryStr) {
    // 检查输入是否为空
    if (binaryStr.empty()) {
        return "";
    }
    
    // 检查输入是否只包含0和1
    for (char c : binaryStr) {
        if (c != '0' && c != '1') {
            throw std::invalid_argument("输入字符串必须只包含0和1");
        }
    }
    
    // 创建二进制到十六进制的映射
    static const std::map<std::string, char> binaryToHexMap = {
        {"0000", '0'}, {"0001", '1'}, {"0010", '2'}, {"0011", '3'},
        {"0100", '4'}, {"0101", '5'}, {"0110", '6'}, {"0111", '7'},
        {"1000", '8'}, {"1001", '9'}, {"1010", 'A'}, {"1011", 'B'},
        {"1100", 'C'}, {"1101", 'D'}, {"1110", 'E'}, {"1111", 'F'}
    };
    
    std::string hexStr;
    int length = binaryStr.length();
    
    // 处理长度不是4的倍数的情况，在前面补0
    int padding = (4 - (length % 4)) % 4;
    std::string paddedBinary = std::string(padding, '0') + binaryStr;
    
    // 每4位二进制转换为1位十六进制
    for (size_t i = 0; i < paddedBinary.length(); i += 4) {
        std::string nibble = paddedBinary.substr(i, 4);
        hexStr += binaryToHexMap.at(nibble);
    }
    
    return hexStr;
}


std::vector<std::string> readTxtFile(const std::string& filePath) {
    std::vector<std::string> lines;
    std::ifstream file(filePath);
    
    // 检查文件是否成功打开
    if (!file.is_open()) {
        std::cerr << "无法打开文件: " << filePath << std::endl;
        return lines;
    }
    
    std::string line;
    // 逐行读取文件内容
    while (std::getline(file, line)) {
        lines.push_back(line);
    }
    
    file.close();
    return lines;
}

bool writeHex(const std::string& filePath, std::vector<std::string>& hexfile, int append)
{
    // 打开文件，append参数决定是追加模式还是覆盖模式
    std::ofstream file;
    if (append) {
        file.open(filePath, std::ios::app); // 追加模式
    } else {
        file.open(filePath); // 覆盖模式（默认）
    }
    
    // 检查文件是否成功打开
    if (!file.is_open()) {
        std::cerr << "无法打开文件: " << filePath << std::endl;
        return false;
    }
    
    // 逐行写入内容
    for (int i=0,j=0; i<hexfile.size(); i++) {
        if(j<7)
        {
            file << hexfile[i] << " ";
            j++;
        }

        else
        {
            file << hexfile[i] << std::endl;
            j = 0;
        }

    }
    
    file.close();
    return true;

}



int main() {

    std::string binFilePath = "./bin.txt";
    std::string hexFilePath = "./hex.txt";
    std::vector<std::string> binfile = readTxtFile(binFilePath);
    std::vector<std::string> hexfile;
    for(std::string binStr : binfile)
    {
        hexfile.emplace_back(binaryToHex(binStr));
    }
    writeHex(hexFilePath, hexfile, 0);
    
    return 0;
}

